
from dash import Output, Input, State, html,dcc,no_update
from models import Product, db, RepairRecord, MaintainRecord
from sqlalchemy import desc
from server import server
# from modules.equipment.layouts import generate_equipment_detail
import dash

from dash import callback_context

from urllib.parse import urlparse, parse_qs
from models import Product
from .runningreport import update_run_report_graph_1,get_running_detail_by_id
from .detail_layout import create_detail_layout

from dash import callback_context
from datetime import datetime

import plotly.graph_objs as go
from dateutil.relativedelta import relativedelta





def get_equipment_detail_by_id(device_id):
    
    product = Product.query.filter_by(id=device_id).first()
    if product:
        return product.to_dict()  # 你需要实现 to_dict 方法
    return None

def register_callbacks(dash_app):
    # print("register equipment detail callback222222222222222")

    def get_equipment_maintain_and_repair_info(device_id):
        # 查询维护记录
        maintain_query = db.session.query(MaintainRecord).filter(
            MaintainRecord.product_id == device_id,
            MaintainRecord.is_active == True
        )
        maintain_count = maintain_query.count()
        last_maintain = maintain_query.order_by(desc(MaintainRecord.actual_date)).first()
        last_maintain_date = last_maintain.actual_date.strftime("%Y-%m-%d") if last_maintain and last_maintain.actual_date else "无"

        # 查询维修记录
        repair_count = db.session.query(RepairRecord).filter(
            RepairRecord.product_id == device_id,
            RepairRecord.is_active == True
        ).count()

        return last_maintain_date, maintain_count, repair_count

    # # 在设备详情回调中调用
    # last_maintain_date, maintain_count, repair_count = get_equipment_maintain_and_repair_info(device_id)
    # # 然后将这三个值填充到页面对应栏目

    # 设备详情展示（增强版）
    def register_equipment_detail_callback(dash_app):
    #    print("callbacks2 p44 register equipment detail callback begin")
       pass


    @dash_app.callback(
        [Output('url-device-detail', 'pathname'), # Output for pathname
         Output('url-device-detail', 'search')],   # Output for search
        [Input('equipment-table', 'selected_rows')],
        [State('equipment-table', 'data')],
        prevent_initial_call=True
    )
    def goto_equipment_detail(selected_rows, table_data):
        print(f"[p60调试 goto_equipment_detail] selected_rows: {selected_rows}")
        if selected_rows and table_data:
            row_index = selected_rows[0]
            if row_index < len(table_data):
                row = table_data[row_index]
                device_id = row.get('id')
                print(f"[调试 goto_equipment_detail] device_id: {device_id}")
                if device_id is not None: # 确保 device_id 不是 None
                    pathname = "/dash/equipment/detail"
                    search = f"?id={device_id}"
                    print(f"[调试 goto_equipment_detail] Returning pathname: {pathname}, search: {search}")
                    return pathname, search
                else:
                    print("[调试 goto_equipment_detail] device_id is None, returning no_update")
                    return dash.no_update, dash.no_update
            else:
                print(f"[调试 goto_equipment_detail] row_index {row_index} out of bounds for table_data length {len(table_data)}")
                return dash.no_update, dash.no_update
        print("[调试 goto_equipment_detail] No selected_rows or no table_data, returning no_update")
        return dash.no_update, dash.no_update

    #   在 register_callbacks 函数内部调用嵌套的注册函数
    register_equipment_detail_callback(dash_app)

    # 新增的 A 标签点击回调函数
    @dash_app.callback(
        [Output('detail-tabs-content', 'children'),
         Output('link-运行报告', 'className'),
         Output('link-重大事件', 'className'),
         Output('link-资产信息', 'className'),
         Output('link-合同记录', 'className'),
         Output('link-绩效分析', 'className'),
         Output('link-绩效目标', 'className'),
         Output('link-其他', 'className'),
         Output('link-实时监控', 'className'),
        ],
        [
            Input('link-运行报告', 'n_clicks'),
            Input('link-重大事件', 'n_clicks'),
            Input('link-资产信息', 'n_clicks'),
            Input('link-合同记录', 'n_clicks'),
            Input('link-绩效分析', 'n_clicks'),
            Input('link-绩效目标', 'n_clicks'),
            Input('link-其他', 'n_clicks'),
            Input('link-实时监控', 'n_clicks'),
        ],
        [State('url-device-detail', 'search')] # Add State to get device_id
    )
    def update_detail_content(*args):
        n_clicks = args[:-1]
        search = args[-1]
        ctx = dash.callback_context
        device_id = None
        if search and search.startswith('?id='):
            query_string = urlparse(search).query
            query_params = parse_qs(query_string)
            device_id_list = query_params.get('id')
            if device_id_list:
                try:
                    device_id = int(device_id_list[0])
                except ValueError:
                    device_id = None
         # 初始化默认content
        content = html.Div("请点击标签查看内容")
        button_id = 'link-运行报告'
        if ctx.triggered:
            button_id = ctx.triggered[0]['prop_id'].split('.')[0]
            
            # 完全清空原有内容，创建全新的内容
            if button_id == 'link-运行报告':
                content = html.Div([
                    html.H3('运行报告详情'),
                    # 这里可以添加全新的组件
                    dcc.Graph(id='new-run-report-graph'),
                    html.Div(id='new-run-report-table')
                ])
            elif button_id == 'link-重大事件':
                content = html.Div([
                    html.H3('重大事件记录'),
                    # 全新的流程图组件
                    dcc.Graph(id='new-event-flowchart')
                ])
            else:
                content = html.Div(f"这里是 {button_id.replace('link-', '')} 的内容")
        class_names = []
        tab_link_ids = ['link-运行报告', 'link-重大事件', 'link-资产信息', 'link-合同记录', 'link-绩效分析', 'link-绩效目标', 'link-其他', 'link-实时监控']
        for input_id in tab_link_ids:
            if input_id == button_id:
                class_names.append('tab-link active')
            else:
                class_names.append('tab-link')
        return [content] + class_names

    # 根据 URL 参数加载设备基本信息
    @dash_app.callback(
        [Output('detail-device-id', 'children'),
         Output('detail-device-name', 'children'),
         Output('detail-device-code', 'children'),
         Output('detail-device-model', 'children'),
         Output('detail-device-sn', 'children'),
         Output('detail-device-org', 'children'),
         Output('detail-device-department', 'children'),
         Output('detail-device-purchase-date', 'children'),
         Output('detail-device-launch-date', 'children'),
         Output('detail-device-price', 'children'),
         Output('detail-device-status', 'children'),
         Output('detail-device-owner', 'children'),
         Output('detail-device-ensure-status', 'children'),
         # ... 其他基本信息字段的 Output
        ],
        [Input('url-device-detail', 'search')], # 明确监听 url-device-detail 的 search
        prevent_initial_call=False # 允许初始加载和刷新时触发
    )
    def update_basic_info(search):
        # print(f"[调试 update_basic_info] triggered with search: {search}")
        device_id = None
        if search and search.startswith('?id='):
            query_string = urlparse(search).query
            query_params = parse_qs(query_string)
            device_id_list = query_params.get('id')
            if device_id_list:
                 device_id_str = device_id_list[0]
                 try:
                     device_id = int(device_id_str)
                 except ValueError:
                     print(f"[调试 update_basic_info] Error converting device_id '{device_id_str}' to int.")
                     device_id = None
            else:
                print(f"[调试 update_basic_info] 'id' not found in query_params: {query_params}")
        elif search:
            print(f"[调试 update_basic_info] search parameter does not start with '?id=': {search}")
        else:
            print("[调试 update_basic_info] search parameter is None or empty.")

        # print(f"[调试 update_basic_info] Parsed device_id: {device_id}")

        if device_id is not None:
            device_info = get_equipment_detail_by_id(device_id)
            # print(f"[调试 update_basic_info] device_info from DB: {device_info}")

            if device_info:
                return (
                    device_id,
                    f" {device_info.get('产品名称', 'N/A')}",
                    f" {device_info.get('资产编号', 'N/A')}",
                    f" {device_info.get('品牌', '无品牌')} {device_info.get('型号', '无型号')} ",
                    f" {device_info.get('序列号', '无序列号')  } ",
                    f" {device_info.get('机构简称', 'N/A')}",
                    f" {device_info.get('所属科室', 'N/A')}",
                    f" {device_info.get('购买日期', 'N/A')}",
                    f" {device_info.get('启用日期', 'N/A')}",
                    f" {device_info.get('价格', 'N/A')}",
                    f" {device_info.get('运行状态', 'N/A')}",
                    f" {device_info.get('责任人', 'N/A')}",
                    f" {device_info.get('保修期限(月)', 'N/A')}",
                )
            else:
                print(f"[调试 update_basic_info] No device_info found for device_id: {device_id}")
                return (
                    "设备id: 未找到","设备名称: 未找到", "设备型号: 未找到", "设备品牌: 未找到",
                    "所属机构: 未找到", "所属部门: 未找到", "购买日期: 未找到",
                    "设备价格: 未找到", "设备状态: 未找到",
                )
        else:
            print("[调试 update_basic_info] device_id is None, returning '请选择设备'")
            # 当 search 为空或解析不到 id 时，也应该返回一些提示信息
            # 或者根据您的需求，返回 dash.no_update 来避免更新 Output
            return (
                "设备名称: 无效ID或未提供ID", "设备型号: 无效ID或未提供ID", "设备品牌: 无效ID或未提供ID",
                "所属机构: 无效ID或未提供ID", "所属部门: 无效ID或未提供ID", "购买日期: 无效ID或未提供ID",
                "设备价格: 无效ID或未提供ID", "设备状态: 无效ID或未提供ID",
            )

    #页面初始化显示运行报告内容
    @dash_app.callback(
        [Output('run-report-graph-1', 'figure'),
         Output('run-report-graph-3', 'figure'),
         Output('run-report-table', 'children'),
         Output('run-report-table3', 'children')],
        [Input('date-picker-range', 'start_date'),
         Input('date-picker-range', 'end_date'),
         Input('detail-device-id', 'data')]
    )
    def update_equipment_detail_outputs(start_date, end_date, device_id):
        print(f"[p232调试 update_equipment_detail_outputs] start_date: {start_date}, end_date: {end_date}, device_id: {device_id}")
        if device_id is None:
            print("[p248调试 update_equipment_detail_outputs] device_id is None, returning no_update")
            return update_run_report_graph_1(0, 0, 0, 0, 0), no_update, no_update, no_update
        repair_count, maintain_count, inspection_count, strong_inspect_count, calibration_count = get_running_detail_by_id(device_id, startdate=start_date, enddate=end_date)
        from datetime import datetime
        fig1 = update_run_report_graph_1(repair_count, maintain_count, inspection_count, strong_inspect_count, calibration_count)
        # 生成月份列表（纯数字）
        months = []
        if start_date and end_date:
            dt_start = datetime.strptime(start_date, '%Y-%m-%d')
            dt_end = datetime.strptime(end_date, '%Y-%m-%d')
            cur = dt_start.replace(day=1)
            while cur <= dt_end:
                months.append(cur.month)  # 只取月份数字
                cur += relativedelta(months=1)
        else:
            months = []
        y_zeros = [0] * len(months)
        fig3 = go.Figure(data=[
            go.Bar(x=months, y=y_zeros, name='收益'),
            go.Bar(x=months, y=y_zeros, name='支出'),
            go.Bar(x=months, y=y_zeros, name='收入'),
            
        ])
        fig3.update_layout(title='绩效分析', xaxis_title='月份', yaxis_title='金额(元）', yaxis_range=[0, 10000], barmode='group')
        if device_id is not None:
            device_info = get_equipment_detail_by_id(device_id)
        # 计算维修成本和故障时长
        from datetime import datetime
        repair_cost = db.session.query(db.func.sum(RepairRecord.repair_cost)).filter(
            RepairRecord.product_id == device_id,
            RepairRecord.is_active == True,
            RepairRecord.actual_completion_date >= start_date,
            RepairRecord.actual_completion_date <= end_date
        ).scalar() or 0
        
        repair_duration = db.session.query(db.func.sum(RepairRecord.repair_duration)).filter(
            RepairRecord.product_id == device_id,
            RepairRecord.is_active == True,
            RepairRecord.actual_completion_date >= start_date,
            RepairRecord.actual_completion_date <= end_date
        ).scalar() or 0
        
        # 计算已使用年限
        purchase_date = device_info.get('购买日期')
        if purchase_date:
            used_years = (datetime.now() - datetime.strptime(purchase_date, '%Y-%m-%d')).days / 365
        else:
            used_years = 3
        std_years =     device_info.get('使用年限', 3)
        age_index =  round(used_years / std_years,2)

        left_table = html.Table([
            html.Tr([html.Td("维修次数："), html.Td(f"{repair_count}")]),
           
            html.Tr([html.Td("保养次数："), html.Td(f"{maintain_count}")]),
            html.Tr([html.Td("巡检次数："), html.Td(f"{inspection_count}")]),
            html.Tr([html.Td("强检次数："), html.Td(f"{strong_inspect_count}")]),
            html.Tr([html.Td("校正次数："), html.Td(f"{calibration_count}")]),
        ], className='run-report-table', style={'width': '48%', 'display': 'inline-block', 'verticalAlign': 'top'})
        
        right_table = html.Table([
            html.Tr([html.Td("标准使用年限："), html.Td(f"{device_info.get('使用年限', 'N/A')} 年")]),
            html.Tr([html.Td("已使用年限："), html.Td(f"{used_years:.2f} 年" if isinstance(used_years, float) else used_years)]),
            html.Tr([html.Td("年限指数："), html.Td(age_index)]),
            html.Tr([html.Td("维修成本："), html.Td(f"￥{repair_cost:.2f} 元")]),
            html.Tr([html.Td("故障时间："), html.Td(f"{repair_duration:.2f} 小时")]),
        ], className='run-report-table', style={'width': '48%', 'display': 'inline-block', 'verticalAlign': 'top', 'marginLeft': '2%'})
        
        table1 = html.Div([
            left_table,
            right_table
        ], style={'width': '100%', 'display': 'flex', 'justifyContent': 'space-between'})
        table3 = html.Div([
            html.Table([
                html.Tr([html.Td("今年收入："), html.Td("￥0.00元")]),
                html.Tr([html.Td("去年同期收入："), html.Td("￥0.00元")]),
                html.Tr([html.Td("同比："), html.Td("100.00%")]),
                
            ], className='run-report-table3', style={'width': '48%', 'display': 'inline-block', 'verticalAlign': 'top'}),
            html.Table([
                html.Tr([html.Td("今年支出："), html.Td("￥0.00元")]),
                html.Tr([html.Td("去年同期支出："), html.Td("￥0.00元")]),
                html.Tr([html.Td("同比："), html.Td("100.00%")]),
                
            ], className='run-report-table3', style={'width': '48%', 'display': 'inline-block', 'verticalAlign': 'top', 'marginLeft': '2%'}),
            html.Table([
                html.Tr([html.Td("服务项次："), html.Td("0 次")]),
                html.Tr([html.Td("回本年限："), html.Td("0 年")]),
            ], className='run-report-table3', style={'width': '48%', 'display': 'inline-block', 'verticalAlign': 'top', 'marginLeft': '2%'})
        ], style={'width': '100%', 'display': 'flex', 'justifyContent': 'space-between'})
        return fig1, fig3, table1, table3


    @dash_app.callback(
        Output('detail-device-id', 'data'),
        [Input('url-device-detail', 'search')]
    )
    def set_detail_device_id(search):
        device_id = None
        if search and search.startswith('?id='):
            query_string = urlparse(search).query
            query_params = parse_qs(query_string)
            device_id_list = query_params.get('id')
            if device_id_list:
                try:
                    device_id = int(device_id_list[0])
                except ValueError:
                    device_id = None
        return device_id




 

    